<template>
  <el-input v-model="loginValidateCode"
            :class="errorClass"
            placeholder="验证码"
            v-on:change="errorClass=''"
            class="input-with-select">
    <template #append>
      <div class="s-canvas" @click="randomCode" :style="{width:contentWidth+'px',height:contentHeight+'px'}">
        <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
      </div>
    </template>
    <template #prefix>
      <el-icon :size="16" >
        <i class="el-icon-v-anquan"></i>
      </el-icon>

    </template>
  </el-input>
</template>

<script lang="ts" setup>
//定义组件名称
defineOptions({
  name: "ImageValid"
});

//接收的参数
const props = defineProps({
  value: {type: String, required: false},
  openCaptcha: {type: Boolean, required: true, default: true}
});
// @ts-ignore
import {ref, onMounted, computed, watchEffect, getCurrentInstance, watch} from 'vue'

let errorClass = ref("");
// @ts-ignore
const {proxy} = getCurrentInstance()

let backgroundColorMin = ref(180);
let backgroundColorMax = ref(200);
let lineColorMin = ref(35);
let lineColorMax = ref(100);
let contentWidth = ref(80);//宽度
let contentHeight = ref(25);//高度
let identifyCode = ref('');//生成的验证码
let loginValidateCode = ref("")//输入的验证码

onMounted(() => {
  randomCode();
});
const emit = defineEmits(['update:value'])

const randomCode = () => {
  proxy.$http.postNoAuth('/cloud/oauth/captcha', {}).then(function (response: any) {
    identifyCode.value = response.data + '';
  });
}

//监听变化返回
watch(() => identifyCode.value, async () => {
  drawPic();
}, {
  // deep: true // 可以不写
})
//监听变化返回
watch(() => loginValidateCode.value, async () => {
  emit("update:value", loginValidateCode.value)

}, {
  // deep: true // 可以不写
})
// 生成一个随机数
let randomNum = (min: number, max: number) => {
  return Math.floor(Math.random() * (max - min) + min);
}

// 生成一个随机的颜色
let randomColor = (min: number, max: number) => {
  let r = randomNum(min, max);
  let g = randomNum(max, min);
  let b = randomNum(min, max);
  return 'rgb(' + r + ',' + g + ',' + b + ')';
}

let drawPic = () => {
  loginValidateCode.value = '';
  setTimeout(function () {
    let canvas: any = document.getElementById('s-canvas');
    let ctx = canvas.getContext('2d');
    ctx.textBaseline = 'bottom';
    // 绘制背景
    ctx.fillStyle = randomColor(backgroundColorMin.value, backgroundColorMax.value); //图形填充颜色设置
    ctx.strokeStyle = randomColor(backgroundColorMin.value, backgroundColorMax.value); //图形轮廓的颜色设置
    ctx.fillRect(0, 0, contentWidth.value, contentHeight.value); //绘制一个填充的矩形 0 0 width height x起点 y起点  宽 高
    ctx.strokeRect(0, 0, contentWidth.value, contentHeight.value); // 绘制一个矩形边框 0 0 width height x起点 y起点  宽 高
    ctx.clearRect(0, 0, contentWidth.value, contentHeight.value);  //清除指定矩形区域，清除部分完全透明
    // 绘制文字
    for (let i = 0; i < identifyCode.value.length; i++) {
      drawText(ctx, identifyCode.value[i], i);
    }
    drawLine(ctx);
    drawDot(ctx);
  }, 100)
}

let drawText = (ctx: any, txt: string, i: number) => {
  ctx.fillStyle = randomColor(backgroundColorMin.value, backgroundColorMax.value);
  ctx.font = 20 + 'px SimHei'; //字体大小
  ctx.textBaseline = 'alphabetic'; //基线对齐
  let x = i * (contentWidth.value / 4);
  let y = contentHeight.value - 5;
  let deg = randomNum(-45, 45);
  // 修改坐标原点和旋转角度
  ctx.translate(x, y);//移动不同位置  参数偏移量
  // ctx.rotate(deg * Math.PI / 180); //旋转 参数角度
  ctx.fillText(txt, 0, 0);
  // 恢复坐标原点和旋转角度
  // ctx.rotate(-deg * Math.PI / 180);
  ctx.translate(-x, -y);
}

let drawLine = (ctx: any) => {
  // 绘制干扰线
  for (let i = 0; i < 4; i++) {
    ctx.strokeStyle = randomColor(lineColorMin.value, lineColorMax.value);
    ctx.beginPath(); //新建一条路径
    ctx.moveTo(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value)); //设置起点x,y
    ctx.lineTo(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value)); //绘制直线 x,y 一条当前位置到x,y点的直线
    ctx.stroke(); // 通过线条绘制图形轮廓
    ctx.closePath(); //结束闭合路径
  }
}

let drawDot = (ctx: any) => {
  // 绘制干扰点
  for (let i = 0; i < 20; i++) {
    ctx.fillStyle = randomColor(0, 255);
    ctx.beginPath();
    // 绘制圆弧或圆，x,y,radius，startAngle,endAngle,anticlockwise // x,y 圆心点，radius 半径，从startAngle开始到endAngle结束
    ctx.arc(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value), 1, -10, 10 * Math.PI);
    ctx.fill(); //通过填充路径的内容区域生成实心的图形。
  }
}


const compareCode = () => {
  let result = true;
  if (props.openCaptcha) {
    result = loginValidateCode.value.toLocaleLowerCase() == identifyCode.value.toLocaleLowerCase();
    if (!result) {
      errorClass.value = ' error-code ';
      randomCode();
    }
  }
  return result;
}

defineExpose({
  compareCode
});
</script>

<style scoped lang="less">
.input-with-select {
  width: 100%;
  height: 40px;
  overflow: hidden;
  padding: 0px;

  .el-input-group__append * {
    padding: 0px;
  }
}

.error-code {
  border: 1px red solid;
  border-radius: 5px;
}


</style>